import java.util.concurrent.locks.*;
/**
 * This class is called CustomLock, it is meant for locking a thread. This class is to be used as such:
 * CustomLock my_thread_1_lock = new CustomLock();
 * 
 * someFunctionThatWritesToAVariableOrIOInterface()
 * {
 * 		//Makes all other threads stop if they are calling lock()
 * 		my_thread_1_lock.lock()
 * 			my_array.size++;//Some alteration
 * 		my_thread_1_lock.unlock();
 * }
 * @author aasierra
 *
 */
public class CustomLock {
	/**
	 * This variable is for telling whether or not this lock is actually locked or unlocked.
	 * The value false means unlocked while the value true means locked.
	 */
	private boolean my_is_locked;
	
	/**
	 * This variable is used to track what thread locked this lock in order to make sure that other
	 * synchronized functions inside the thread are still able to be activated.
	 */
	private Thread my_locked_by_thread;

	/**
	 * When locking a thread and then calling another function within that same thread that calls
	 * lock the locked count is increased and decreased in order to keep track of the amount of unlocks
	 * needed before the thread can be left. For instance
	 * somefunc()
	 * {
	 * 		my_lock.lock()
	 * 		func2();
	 * 		my_lock.unlock();
	 * }
	 * func2()
	 * {
	 * 		my_lock.lock()
	 * 		func2();
	 * 		my_lock.unlock();
	 * }
	 * it keeps track that locked was called twice in this thread and makes sure that the same amount of
	 * unlocks are called.
	 */
	private int my_locked_count;
	
	/**
	 * The default constructor that sets this lock object to unlocked.
	 */
	public CustomLock()
	{
		my_is_locked = false;
		my_locked_count = 0;
	}
	/**
	 * Locks the current thread making it the priority.
	 * @throws InterruptedException
	 */
	public synchronized void lock() throws InterruptedException
	{
		Thread call_thread = Thread.currentThread();
		while (my_is_locked && my_locked_by_thread != call_thread) {
			wait();
		}
		my_locked_count++;
		my_is_locked 		= true;
		my_locked_by_thread = call_thread;
	}
	
	/**
	 * Unlocks the current thread giving other threads the priority.
	 */
	public synchronized void unlock()
	{
		if (Thread.currentThread() == my_locked_by_thread)
		{
			my_locked_count--;
			if (my_locked_count == 0)
			{
				my_is_locked = false;
				notifyAll();
			}
		}
	}

}
